home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / source / exec / semaphores / src / obtainsemaphore.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  2.1 KB  |  97 lines

  1. /*
  2.     $Id$
  3.     $Log$
  4.     Desc:
  5.     Lang: english
  6. */
  7. #include "exec_intern.h"
  8. #include "semaphores.h"
  9.  
  10. /*****************************************************************************
  11.  
  12.     NAME */
  13.     #include <exec/semaphores.h>
  14.     #include <clib/exec_protos.h>
  15.  
  16.     __AROS_LH1(void, ObtainSemaphore,
  17.  
  18. /*  SYNOPSIS */
  19.     __AROS_LA(struct SignalSemaphore *, sigSem, A0),
  20.  
  21. /*  LOCATION */
  22.     struct ExecBase *, SysBase, 94, Exec)
  23.  
  24. /*  FUNCTION
  25.     Obtain an exclusive lock on a semaphore. If the semaphore is already
  26.     in use by another task this function will wait until the semaphore
  27.     becomes free.
  28.  
  29.     INPUTS
  30.     sigSem - Pointer to semaphore structure
  31.  
  32.     RESULT
  33.  
  34.     NOTES
  35.     This function preserves all registers.
  36.  
  37.     EXAMPLE
  38.  
  39.     BUGS
  40.  
  41.     SEE ALSO
  42.     ReleaseSemaphore()
  43.  
  44.     INTERNALS
  45.  
  46.     HISTORY
  47.     29-10-95    digulla automatically created from
  48.                 exec_lib.fd and clib/exec_protos.h
  49.     21-01-96    fleischer implementation
  50.  
  51. *****************************************************************************/
  52. {
  53.     __AROS_FUNC_INIT
  54.     __AROS_BASE_EXT_DECL(struct ExecBase *,SysBase)
  55.     struct Task *me;
  56.  
  57.     /* Get pointer to current task */
  58.     me=SysBase->ThisTask;
  59.  
  60.     /* Arbitrate for the semaphore structure */
  61.     Forbid();
  62.  
  63.     /* Check if the semaphore is in use by another task */
  64.     if(sigSem->ss_NestCount&&sigSem->ss_Owner!=me)
  65.     {
  66.     /*
  67.         I wish there was some shared memory available as a semaphore node.
  68.         Unfortunately it isn't - and I cannot rely on being able to get
  69.         some from AllocMem() at this point either, so I have to use a part
  70.         of the stack instead :-(.
  71.     */
  72.     struct SemaphoreNode sn;
  73.  
  74.     sn.node.ln_Pri =SN_TYPE_OBTAIN;
  75.     sn.node.ln_Name=(char *)SM_EXCLUSIVE;
  76.     sn.task        =me;
  77.  
  78.     /* Add the node to the semaphore's waiting queue. */
  79.     AddTail((struct List *)&sigSem->ss_WaitQueue,&sn.node);
  80.  
  81.     /* Wait until the semaphore is free */
  82.     Wait(SEMAPHORESIGF);
  83.  
  84.     /* ss_NestCount and ss_Owner are already set by ReleaseSemaphore() */
  85.     }else
  86.     {
  87.     /* The semaphore is free - take it over */
  88.     sigSem->ss_NestCount++;
  89.     sigSem->ss_Owner=me;
  90.     }
  91.  
  92.     /* All done */
  93.     Permit();
  94.     __AROS_FUNC_EXIT
  95. } /* ObtainSemaphore */
  96.  
  97.